﻿using UnityEngine;
using System;
using System.IO;
using xuni;

namespace xres
{


    public static class ResPath
    {

        /// <summary>
        /// <para>一般在Editor下测试热更时设为true, 此时会从Proj/_EditorHotfix/Bundles下读取。</para>
        /// <para>平时正常的开发, 一般设为false, 此时会直接从Proj/Assets/StreamingAssets/Bundles下读取,
        /// 修改后的打完Bundle就可直接看到, 不需要走一次热更。</para>
        /// </summary>
#if UNITY_EDITOR
        public const bool Editor_Hotfix_Enable = false;
#else
        public const bool Editor_Hotfix_Enable = false;
#endif

#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
        public const bool PC_Hotfix_Enable = false;
#endif

        public const string Bundle_Ext = ".bin";

        static string s_internalBundleDir = "";
        public static string InternalBundleDir { get { return s_internalBundleDir; } }

        static string s_externalDir = "";

        /// <summary>
        /// Bundle包所在文件夹(热更)
        /// </summary>
        static string s_externalBundleDir = "";
        public static string ExternalBundleDir { get { return s_externalBundleDir; } }


        public static void Initialize(string bundleDir, bool usePlatform)
        {
            if (!string.IsNullOrEmpty(s_internalBundleDir)) //has init
                return;

            var sb = xuni.StringUtils.Builder;
            if (!string.IsNullOrEmpty(bundleDir))
            {
                if (!PathUtils.IsFirstCharSeparator(bundleDir))
                    sb.Append('/');

                sb.Append(bundleDir);

                if (!PathUtils.IsLastCharSeparator(bundleDir))
                {
                    sb.Append('/');
                }
            }
            else
            {
                sb.Append('/');
            }

            if (usePlatform)
            {
                sb.Append(ResPath.PlatformName).Append('/');
            }

            var dir = sb.Replace('\\', '/').BuildString();

#if UNITY_EDITOR //UNITY_EDITOR_WIN, UNITY_EDITOR_OSX
            //开发模式
            if (Editor_Hotfix_Enable)
            {
                s_externalDir = sb.Append(Application.dataPath).Replace("Assets", "_EditorHotfix").Replace('\\', '/').ToString();
                //类似: d:/Unity/xRes/_EditorHotfix/Bundles/Windows/
            }
            else
            {
                s_externalDir = sb.Append(Application.streamingAssetsPath).Replace('\\', '/').ToString();
                // d:/Unity/xRes/Assets/StreamingAssets/Bundles/Windows/
            }
#elif UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
            if (PC_Hotfix_Enable)
            {
                //类似: C:/Users/{User_Name}/AppData/LocalLow/{Company_Name}/{App_Name}/Bundles/Windows/
                s_externalDir = sb.Append(Application.persistentDataPath).Replace('\\', '/').ToString();
            }
            else
            {
                s_externalDir = sb.Append(Application.streamingAssetsPath).Replace('\\', '/').ToString();
            }
#elif UNITY_ANDROID
            s_externalDir = sb.Append(Application.persistentDataPath).Replace('\\', '/').ToString();
#elif UNITY_IPHONE || UNITY_IOS
            s_externalDir = sb.Append(Application.persistentDataPath).Replace('\\', '/').ToString();
#else
            s_externalDir = sb.Append(Application.streamingAssetsPath).Replace('\\', '/').ToString();
#endif
            s_externalBundleDir = sb.Append(dir).BuildString();

            s_internalBundleDir = sb.Append(Application.streamingAssetsPath).Append(dir).Replace('\\', '/').BuildString();

            Debug.Log($"PathUtils: Initialize: External: {s_externalBundleDir}, Internal: {s_internalBundleDir}");
        }

        public static string PlatformName
        {
            get
            {
                //使用宏的弊端: 不手动切为指定平台, 是不能使用其他平台的
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
                return "Windows";
#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
            return "MacOS";
#elif UNITY_IPHONE || UNITY_IOS
            return "iOS";
#elif UNITY_ANDROID
            return "Android";
#else
            Debug.LogError($"unsupport platform: {Application.platform}");
            return "Unsupport";
#endif
            }
        }

        public static string BuildExternalPath(string path)
        {
            var sb = xuni.StringUtils.Builder;
            return sb.Append(s_externalDir).Append(path).Replace('\\', '/').BuildString();
        }

        public static string BuildExternalTempBundlePath(string path)
        {
            var sb = xuni.StringUtils.Builder;
            return sb.Append(s_externalBundleDir).Append("Temp/").Append(path).Replace('\\', '/').BuildString();
        }

        public static string BuildExternalBundlePath(string path)
        {
            var sb = xuni.StringUtils.Builder;
            return sb.Append(s_externalBundleDir).Append(path).Replace('\\', '/').BuildString();
        }

        public static void DeleteExternalBundleDir()
        {
            Directory.Delete(s_externalBundleDir, true);
        }

        public static string BuildInternalBundlePath(string path)
        {
            var sb = xuni.StringUtils.Builder;
            return sb.Append(s_internalBundleDir).Append(path).Replace('\\', '/').BuildString();
        }

        public static string BundleNameWithExt(string bundleName)
        {
#if UNITY_EDITOR
            for (var i = bundleName.Length - 1; i >= 0; --i)
            {
                var c = bundleName[i];
                if (c >= 'A' && c <= 'Z')
                {
                    Debug.LogError($"Bundle名需要全小写: {bundleName}");
                    break;
                }
            }
#endif

            if (!bundleName.EndsWith(ResPath.Bundle_Ext, StringComparison.OrdinalIgnoreCase))
            {
                var sb = xuni.StringUtils.Builder;
                return sb.Append(bundleName).Append(ResPath.Bundle_Ext).BuildString();
            }

            return bundleName;
        }

        public static string AssetPathNoExt(string assetPath)
        {
#if UNITY_EDITOR
            for (var i = assetPath.Length - 1; i >= 0; --i)
            {
                var c = assetPath[i];
                if ('/' == c || '\\' == c)
                    break;

                if (c >= 'A' && c <= 'Z')
                {
                    Debug.LogError($"资源名需要全小写: {assetPath}");
                    break;
                }
            }
#endif

            var index = assetPath.LastIndexOf('.');
            if (index >= 0)
            {
                var sb = xuni.StringUtils.Builder;
                sb.Append(assetPath).Remove(index, assetPath.Length - index);

                assetPath = sb.BuildString();
            }
            //Debug.Log($"AssetPathNoExt: {assetPath}");

            return assetPath;
        }

    } //end of class


}